package fr.obsmip.sedoo.client;

import java.util.HashMap;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.Widget;

import fr.obsmip.sedoo.client.event.ExperimentalSiteNavigationEvent;
import fr.obsmip.sedoo.client.event.ExperimentalSiteNavigationEventHandler;
import fr.obsmip.sedoo.client.event.ObservatoryNavigationEvent;
import fr.obsmip.sedoo.client.event.ObservatoryNavigationEventHandler;
import fr.obsmip.sedoo.client.event.UserLogoutEvent;
import fr.obsmip.sedoo.client.mvp.AppActivityMapper;
import fr.obsmip.sedoo.client.mvp.AppPlaceHistoryMapper;
import fr.obsmip.sedoo.client.mvp.MenuPresenterImpl;
import fr.obsmip.sedoo.client.mvp.Presenter;
import fr.obsmip.sedoo.client.place.ExperimentalSiteEditingPlace;
import fr.obsmip.sedoo.client.place.ExperimentalSiteEntryDisplayingPlace;
import fr.obsmip.sedoo.client.place.FilteringHistorian;
import fr.obsmip.sedoo.client.place.ObservatoryEditingPlace;
import fr.obsmip.sedoo.client.place.ObservatoryEntryDisplayingPlace;
import fr.obsmip.sedoo.client.place.WelcomePlace;
import fr.obsmip.sedoo.client.service.SystemService;
import fr.obsmip.sedoo.client.service.SystemServiceAsync;
import fr.obsmip.sedoo.client.ui.HeaderView;
import fr.obsmip.sedoo.client.ui.SectionHeaderView;
import fr.obsmip.sedoo.client.ui.breadcrumb.MetadataBreadcrumb;
import fr.obsmip.sedoo.client.ui.misc.LocalNotificationMole;
import fr.obsmip.sedoo.shared.constant.LogConstant;
import fr.obsmip.sedoo.shared.domain.RBVUserDTO;
import fr.sedoo.commons.client.event.MaximizeEvent;
import fr.sedoo.commons.client.event.MaximizeEventHandler;
import fr.sedoo.commons.client.event.MinimizeEvent;
import fr.sedoo.commons.client.event.MinimizeEventHandler;
import fr.sedoo.commons.client.event.NotificationEvent;
import fr.sedoo.commons.client.event.NotificationHandler;
import fr.sedoo.commons.client.event.PlaceNavigationEvent;
import fr.sedoo.commons.client.event.PlaceNavigationEventHandler;
import fr.sedoo.commons.client.language.place.LanguageSwitchPlace;
import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.user.AuthenticatedUser;
import fr.sedoo.commons.client.util.StringUtil;
import fr.sedoo.commons.client.widget.DialogBoxTools;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class PortailRBV implements EntryPoint, MaximizeEventHandler, MinimizeEventHandler, NotificationHandler, ExperimentalSiteNavigationEventHandler, ObservatoryNavigationEventHandler, PlaceNavigationEventHandler {

	private Place defaultPlace = new WelcomePlace();
	private SimpleLayoutPanel centerPanel =  new SimpleLayoutPanel();
	private DockLayoutPanel mainPanel;
	private static ClientFactory clientFactory;
	private static Presenter presenter;
	private Widget west;
	private SplitLayoutPanel splitPanel;
	
	private DockLayoutPanel largeHeader;
	private HeaderView headerView;
	private SectionHeaderView sectionHeaderView;
	private DockLayoutPanel headerFirstPart;
	private LocalNotificationMole notificationMole;
	
	private static HashMap<String , String> parameters = new HashMap<String, String>();
	
	private static final String MINIMIZED_SIZE="1039px";
	private static final String MAXIMIZED_SIZE="100%";

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		GWT.<GlobalBundle>create(GlobalBundle.class).css().ensureInjected();
		clientFactory = getClientFactory();
		
		presenter = new MenuPresenterImpl(clientFactory);
		guiInit(clientFactory);
		EventBus eventBus = clientFactory.getEventBus();
		
		PlaceController placeController = clientFactory.getPlaceController();
		
		RootPanel loadingMessage = RootPanel.get("loadingMessage");
		if (loadingMessage != null)
		{
			DOM.setInnerHTML(loadingMessage.getElement(), "");
		}
		
		// Start ActivityManager for the main widget with our ActivityMapper
	    ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
		ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
		activityManager.setDisplay(centerPanel);

		// Start PlaceHistoryHandler with our PlaceHistoryMapper
		AppPlaceHistoryMapper historyMapper= GWT.create(AppPlaceHistoryMapper.class);
		FilteringHistorian historian = new FilteringHistorian();
		String name = LanguageSwitchPlace.class.getName();
		historian.addToken(name.substring(name.lastIndexOf('.')+1));
		
		PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper,historian);
		historyHandler.register(placeController, eventBus, defaultPlace);

		DockLayoutPanel centeringPanel = new DockLayoutPanel(Unit.EM);
		centeringPanel.add(mainPanel);
		centeringPanel.setStyleName("background");
		notificationMole = new LocalNotificationMole();
		RootLayoutPanel.get().add(notificationMole);
		RootLayoutPanel.get().add(centeringPanel);
		Window.enableScrolling(false);
	    Window.setMargin("0px");
		// Goes to the place represented on URL else default place
		historyHandler.handleCurrentHistory();
		
		//On force la fermeture des stack admin et provider
		getClientFactory().getEventBus().fireEvent(new UserLogoutEvent());
		
		SystemServiceAsync systemService = GWT.create(SystemService.class);
		
		systemService.getParameters(new AsyncCallback<HashMap<String,String>>() {
			
			@Override
			public void onSuccess(HashMap<String, String> result) {
				setParameters(result);
				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				DialogBoxTools.modalAlert(CommonMessages.INSTANCE.error(), CommonMessages.INSTANCE.anErrorHasOccurred()+" : "+caught.getMessage());
			}
		});
		
		
	}

	private void guiInit(ClientFactory clientFactory) 
	{
		mainPanel = new DockLayoutPanel(Unit.PX);
		mainPanel.setStyleName("background");
		mainPanel.getElement().getStyle().setProperty("border","white solid 0px");
		mainPanel.getElement().getStyle().setProperty("boxShadow","1px 1px 5px 1px rgba(0, 0, 0, 0.7)");
		mainPanel.setWidth(MINIMIZED_SIZE);
		mainPanel.getElement().getStyle().setProperty("margin", "auto");
		
		headerFirstPart = new DockLayoutPanel(Unit.PX);
		headerView = clientFactory.getHeaderView();
		headerFirstPart.addNorth(headerView, 147);
		headerFirstPart.addSouth(clientFactory.getBreadCrumb(), 25);
		
		
		largeHeader = new DockLayoutPanel(Unit.PX);
		largeHeader.addNorth(headerFirstPart, 172);
		sectionHeaderView = clientFactory.getSectionHeaderView();
		largeHeader.addSouth(sectionHeaderView, 50);
		
		mainPanel.addNorth(largeHeader,222);
		splitPanel = new SplitLayoutPanel();
		west = clientFactory.getMenuView().asWidget();
		splitPanel.addWest(west, 210);
		clientFactory.getStatusBarView().asWidget();
		mainPanel.addSouth(clientFactory.getStatusBarView(), clientFactory.getStatusBarView().getHeight());
		splitPanel.add(centerPanel);
		mainPanel.add(splitPanel);
		
		clientFactory.getEventBus().addHandler(MaximizeEvent.TYPE, this);
		clientFactory.getEventBus().addHandler(MinimizeEvent.TYPE, this);
		clientFactory.getEventBus().addHandler(NotificationEvent.TYPE, this);
		clientFactory.getEventBus().addHandler(ObservatoryNavigationEvent.TYPE, this);
		clientFactory.getEventBus().addHandler(ExperimentalSiteNavigationEvent.TYPE, this);
		clientFactory.getEventBus().addHandler(PlaceNavigationEvent.TYPE, this);
	}
	
	public static ClientFactory getClientFactory() {
		if (clientFactory == null)
		{
			clientFactory = GWT.create(ClientFactory.class);
		}
		return clientFactory;
	}
	
	public static Presenter getPresenter()
	{
		return presenter;
	}
	
	public static String getParameter(String key)
	{
		String aux = parameters.get(key);
		if (aux == null)
		{
			aux="";
		}
		return aux;
	}

	public static void logout() {
		AuthenticatedUser user = PortailRBV.getClientFactory().getUserManager().getUser();
		if (user != null)
		{
			PortailRBV.getClientFactory().getUserManager().clearCurrentUser();
			getClientFactory().getEventBus().fireEvent(new UserLogoutEvent());
			getPresenter().goTo(new WelcomePlace());
			Logger.addLog((RBVUserDTO) user, LogConstant.SESSION_CATEGORY, LogConstant.DECONNEXION_ACTION, "User "+user.getName()+" has logged off.");
		}
	}

	@Override
	public void onNotification(MinimizeEvent event) {
		splitPanel.setWidgetHidden(west, false);
		headerFirstPart = new DockLayoutPanel(Unit.PX);
		headerView = clientFactory.getHeaderView();
		headerFirstPart.addNorth(headerView, 147);
		headerFirstPart.addSouth(clientFactory.getBreadCrumb(), 25);
		largeHeader.clear();
		largeHeader.addNorth(headerFirstPart, 172);
		mainPanel.setWidgetSize(largeHeader, 222);
		sectionHeaderView = clientFactory.getSectionHeaderView();
		largeHeader.addSouth(sectionHeaderView, 50);
		mainPanel.setWidgetHidden(largeHeader, false);
		mainPanel.setWidth(MINIMIZED_SIZE);
		splitPanel.animate(500);
		headerFirstPart.animate(100);
		mainPanel.animate(500);
		
	}

	@Override
	public void onNotification(MaximizeEvent event) {
		splitPanel.setWidgetHidden(west, true);
		mainPanel.setWidgetSize(largeHeader, 25);
		largeHeader.clear();
		largeHeader.addSouth(clientFactory.getBreadCrumb(), 25);
		mainPanel.setWidth(MAXIMIZED_SIZE);
		splitPanel.animate(500);
		headerFirstPart.animate(100);
		mainPanel.animate(500);
	}
	
	@Override
	public void onNotification(NotificationEvent event) {
		showMole(event.getMessage());
		if (notificationMole != null) {
		}		
	}


	private void showMole(String message) {
		
		
		notificationMole.setAnimationDuration(400);
		notificationMole.addStyleName("notif");
		notificationMole.getElement().getStyle().setProperty("zIndex", ""+fr.sedoo.commons.client.widget.DialogBoxTools.getHigherZIndex());
		notificationMole.getElement().getStyle().setProperty("position", "absolute");
		notificationMole.getElement().getStyle().setProperty("left", "0");
		notificationMole.getElement().getStyle().setProperty("top", "0");
		notificationMole.setWidth("200px");

		notificationMole.show(message);
			Timer timer = new Timer() {
				@Override
				public void run() {
					notificationMole.hide();
				}
			};
			timer.schedule(2500);
		
	}

	public HashMap<String , String> getParameters() {
		return parameters;
	}

	public void setParameters(HashMap<String , String> parameters) {
		this.parameters = parameters;
	}

	@Override
	public void onNotification(ObservatoryNavigationEvent event) 
	{
		if (StringUtil.isNotEmpty(event.getObservatoryName()))
		{
			if (event.getMode() == MetadataBreadcrumb.DISPLAY_MODE)
			{
				ObservatoryEntryDisplayingPlace observatoryEntryDisplayingPlace = new ObservatoryEntryDisplayingPlace();
				observatoryEntryDisplayingPlace.setUuid(event.getObservatoryUuid());
				getPresenter().goTo(observatoryEntryDisplayingPlace);
			}
			else
			{
				ObservatoryEditingPlace observatoryEditingPlace = new ObservatoryEditingPlace();
				observatoryEditingPlace.setObservatoryUuid(event.getObservatoryUuid());
				getPresenter().goTo(observatoryEditingPlace);
			}
		}
	}
	
	@Override
	public void onNotification(ExperimentalSiteNavigationEvent event) 
	{
		if (StringUtil.isNotEmpty(event.getExperimentalSiteName()))
		{
			if (event.getMode() == MetadataBreadcrumb.DISPLAY_MODE)
			{
				ExperimentalSiteEntryDisplayingPlace place = new ExperimentalSiteEntryDisplayingPlace();
				place.setUuid(event.getExperimentalSiteUuid());
				getPresenter().goTo(place);
			}
			else
			{
				ExperimentalSiteEditingPlace place = new ExperimentalSiteEditingPlace();
				place.setExperimentalSiteUuid(event.getExperimentalSiteUuid());
				getPresenter().goTo(place);
			}
		}
	}

	@Override
	public void onNotification(PlaceNavigationEvent event) {
		getPresenter().goTo(event.getPlace());
	}

  
}
